/**    
 * 文件名：RoomPwdEffectiveTimeManage.java</br>
 *    
 * 版本信息：v1.0</br>
 * 日期：2017年9月4日</br>
 * © 2005-2017 雷技信息科技（上海）有限公司版权所有</br>
 *
 */
package com.logic.landseaserver.service.impl;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.logic.landseaserver.common.LandseaErrorMessageEnum;
import com.logic.landseaserver.common.enums.LeaseCodeEnum;
import com.logic.landseaserver.common.exception.LandseaException;
import com.logic.landseaserver.common.util.DateUtil;
import com.logic.landseaserver.domain.BillDetail;
import com.logic.landseaserver.domain.Contract;
import com.logic.landseaserver.persistence.read.BillDetailReadMapper;
import com.logic.landseaserver.persistence.read.ContractReadMapper;
import com.logic.system.service.IConfigurationService;

/**
 *
 * 项目名称：system-server</br>
 * 类名称：RoomPwdEffectiveTimeManage</br>
 * 类描述：门锁密码有效期管理类</br>
 * 创建人：Aaron</br>
 * 创建时间：2017年9月4日 下午3:57:40</br>
 * 
 * @version 1.0
 *
 */
@Service
public class RoomPwdEffectiveTimeManage
{
    private static final Logger LOG = LoggerFactory.getLogger(RoomPwdEffectiveTimeManage.class);
    
    @Autowired
    private ContractReadMapper contractReadMapper;
    
    @Autowired
    private IConfigurationService configurationService;
    
    @Autowired
    private BillDetailReadMapper billDetailReadMapper;
    
    /**
     * [简要描述]：发送密码的有效期</br>
     * [详细描述]：</br>
     * [作者]：Aaron(2017-07-03)</br>
     *
     * @param roomId 房间id
     * @param bodyParamMap 参数
     * @param pwdEndTime 门锁失效时间（禁止设置为过去的时间，不然会失败）,如果为null，则根据账单实际情况走
     * @throws LandseaException
     */
    public Map<String,Object> sendPasswordEffectiveTime(Integer roomId, Map<String, Object> bodyParamMap, Date pwdEndTime)
        throws LandseaException
    {
        Map<String, Object> resultMap = new HashMap<String,Object>();
        
        try
        {
            // 有效期开始时间为当前时间往前推5分钟,获取秒级时间戳
            Calendar currentCalendar = Calendar.getInstance();
            currentCalendar.add(Calendar.MINUTE, -5);
            int beginTime = DateUtil.getSecondTimestamp(currentCalendar.getTime());
            
            // 开始日期就是当前时间
            bodyParamMap.put("permission_begin", beginTime);
            
            // 如果传了时间
            if (null != pwdEndTime)
            {
                int endTime = DateUtil.getSecondTimestamp(pwdEndTime);
                bodyParamMap.put("permission_end", endTime);
                resultMap.put("sendSmsEndTime", endTime);
                return resultMap;
            }
            
            // 查询合同，如果是续租，可以查询
            Contract contract = contractReadMapper.getByRoomId(roomId);
            if (null == contract)
            {
                LOG.error("门锁密码有效期|sendPasswordEffectiveTime|Error|can not find constract with roomId=" + roomId);
                throw LandseaException.createException(LandseaErrorMessageEnum.DDINGLOCK_NONE_CONSTRACT_ERROR);
            }
            
            // 判断租期是否为一个月(不存在2个月的情况)
            if (LeaseCodeEnum.LEAS1.getCode().equals(contract.getLease()))
            {
                contractExpireSetTime(bodyParamMap, resultMap, contract);
                return resultMap;
            }
            
            // 如果当前时间月结账单已出，但租客还未交房租，禁止发送密码
            // 根据合同id，查询房租(billDetail中type为_CTBI8)账单
            Map<String,Object> paramMap = new HashMap<String,Object>();
            paramMap.put("contractId", contract.getId());
            // 此处不需要账单状态的查询条件
            BillDetail billDetail = billDetailReadMapper.selectLastEndDateByContractId(paramMap);
            if (null == billDetail)
            {
                LOG.error("Dding|sendPasswordEffectiveTime|can not find billDetail with contractId=" + contract.getId());
                throw LandseaException.createException(LandseaErrorMessageEnum.DEPOSIT_BILL_NOT_EXISTS_NULL);
            }
/*            BillDTO billDTO = billReadMapper.selectByPrimaryKey(billDetail.getBillId());
            if (null == billDTO)
            {
                LOG.error("Dding|sendPasswordEffectiveTime|can not find bill with billId=" + billDetail.getBillId());
                throw LandseaException.createException(LandseaErrorMessageEnum.DEPOSIT_BILL_NOT_EXISTS_NULL);
            }
            if (!BillStatusEnum.BIST2.getCode().equals(billDTO.getBillStatus()))
            {
                LOG.error("Dding|sendPasswordEffectiveTime|月租未支付完成，无法发送密码");
                //throw LandseaException.createException(LandseaErrorMessageEnum.DDINGLOCK_NONE_PAY_SENDPWD_ERROR);
            }*/
            
            // 下一个月月份
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, 1);
            int nextMonth = calendar.get(Calendar.MONTH);
            int nextMonthYeah = calendar.get(Calendar.YEAR);
            
            Date outDate = contract.getOutDate();
            Calendar calendarEndDate = Calendar.getInstance();
            calendarEndDate.setTime(outDate);
            int endDateMonth = calendarEndDate.get(Calendar.MONTH);
            int endDateMonthYeah = calendarEndDate.get(Calendar.YEAR);
            
            // 判断当前月份 + 1 >= 合同到期月份
            if (nextMonthYeah == endDateMonthYeah && nextMonth >= endDateMonth)
            {
                contractExpireSetTime(bodyParamMap, resultMap, contract);
                return resultMap;
            }
            
            // 如果不满足以上，则走以下逻辑
            // 已交房租日期（月底）23：59分59秒 + payDayTime时长 + payLastDayTime时长（可配置）
            //（短信通知中密码有效期已交房租日期（月底）23：59分59秒）
            // 根据合同id，查询房租(billDetail中type为_CTBI8)账单支付完成的截至日期
            Calendar sendSmsExprieCanendar = Calendar.getInstance();
            sendSmsExprieCanendar.setTime(billDetail.getDateEnd());
            sendSmsExprieCanendar.set(Calendar.DAY_OF_MONTH, sendSmsExprieCanendar.getActualMaximum(Calendar.DAY_OF_MONTH));  
            sendSmsExprieCanendar.set(Calendar.HOUR_OF_DAY, 23);
            sendSmsExprieCanendar.set(Calendar.MINUTE, 59);
            sendSmsExprieCanendar.set(Calendar.SECOND, 59);
            int sendSmsEndTime = DateUtil.getSecondTimestamp(sendSmsExprieCanendar.getTime());
            resultMap.put("sendSmsEndTime", sendSmsEndTime);
            
            // 实际到期为下个月payDayTime时长 + payLastDayTime时长（可配置）
            // int lateFeeDays = Integer.parseInt(configurationService.getStringValue(ConfigurationService.SYS_TIM_FOR_LAT_FEE));
            // int payLastDayTime =
            //    Integer.parseInt(configurationService.getStringValue(ConfigurationService.PAY_LAST_DAY_TIME));
            // 从合同获取
            int lateFeeDays = contract.getLatefeeDay();
            int payLastDayTime = contract.getLastPayDay();
            
            // 截止到12:00:00
            Calendar exprieCanendar = Calendar.getInstance();
            exprieCanendar.setTime(billDetail.getDateEnd());
            exprieCanendar.add(Calendar.MONTH, 1);
            exprieCanendar.set(Calendar.DAY_OF_MONTH, lateFeeDays + payLastDayTime);
            exprieCanendar.set(Calendar.HOUR_OF_DAY, 12);
            exprieCanendar.set(Calendar.MINUTE, 0);
            exprieCanendar.set(Calendar.SECOND, 0);
            
            int endTime = DateUtil.getSecondTimestamp(exprieCanendar.getTime());
            
            bodyParamMap.put("permission_end", endTime);
            
            return resultMap;
        }
        catch (Exception e)
        {
            LOG.error("sendPasswordEffectiveTime | error,RoomId=" + roomId, e);
            throw LandseaException.createException(LandseaErrorMessageEnum.DDINGLOCK_GET_PWD_PERMISSION_ERROR, e);
        }
    }
    
    /**
     * 
     * [简要描述]：
     * 有效期：合同到期 + 缓冲3天（可配置）中午12：00 （短信通知中密码有效期不含缓冲的时间）</br>
     * [作者]：Aaron(2017-09-04)</br>
     *
     * @param bodyParamMap
     * @param contractId
     * @throws LandseaException 
     *
     */
    private void contractExpireSetTime(Map<String, Object> bodyParamMap, Map<String, Object> resultMap, Contract contract) throws LandseaException
    {
        /*
         * 有效期：合同到期 + 缓冲3天（可配置）中午12：00 （短信通知中密码有效期不含缓冲的时间）
         */
        Date outDate = contract.getOutDate();
        
        // 往后推x天中午12点
        // 获取合同到期门锁密码延期失效时间（单位天）
        int delayDayInt = Integer.parseInt(configurationService.getStringValue("EXPIRE_CONTRACT_DOORPWD_DELAY_TIME"));
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(outDate);
        calendar.add(Calendar.DAY_OF_MONTH, delayDayInt);
        calendar.set(Calendar.HOUR_OF_DAY, 12);
        
        Date endDate = calendar.getTime();
        
        int endTime = DateUtil.getSecondTimestamp(endDate);
        
        bodyParamMap.put("permission_end", endTime);
        
        // 发送短信中有效期是不含x天的缓冲的
        int sendSmsEndTime = DateUtil.getSecondTimestamp(outDate);
        resultMap.put("sendSmsEndTime", sendSmsEndTime);
    }
}
